package serveur;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;


public class AccepterConnexion implements Runnable {

	private ServerSocket socketserver;
	private Socket socket;
	private BufferedReader in;
	private DataOutputStream out;
	private String message;
	private static int nbjoueurs;
	private static int numPartieCourante;
	protected static ArrayList<Partie> listeParties;


	AccepterConnexion(ServerSocket _socketserver) 
			throws IOException{
		this.socketserver = _socketserver;
		socket = null;
		listeParties = new ArrayList<Partie>();
		nbjoueurs = 0;
		numPartieCourante = 0;
	}

	protected void connexionSocketClient() throws IOException{
		//Connexion du client a la socket
		socket=socketserver.accept();

		System.out.println("Un joueur/client veut se connecter.");

		//creation flux entrant
		in = new BufferedReader(
				new InputStreamReader(
						socket.getInputStream()) );

		//lecture du flux entrant dans message
		message = in.readLine();

		System.out.println(
				socket.getRemoteSocketAddress()+
				" : "+message);

		//creation du flux de sortie
		out = new DataOutputStream(		
				socket.getOutputStream()
				);
	}

	@Override
	public synchronized void run() {
		try {
			while(true){

				connexionSocketClient();

				//Test de la commande de connexion
				if (message.startsWith(Commande.CONNECT) &&
						message.endsWith("/")){
					message = message.substring(0, message.length()-1);
					String[] tabChaines = message.split("/");

					if(tabChaines.length < 2){
						out.write(Commande.ACCESSDENIED.getBytes());
						in.close();
						out.close();
						socket.close();
					}

					else{
						String nom = tabChaines[1];

						System.out.println("Nom du joueur : "+tabChaines[1]);
						
						System.out.println("Numero de la partie courante : "+numPartieCourante);
						
						//si 1er joueur ou partie pleine => creation partie
						if((nbjoueurs==0) || listeParties.get(numPartieCourante).isFull()){
							creerPartie();
						}
										
						//Gestion nom user deja existant
						for( Joueur player : listeParties.get(numPartieCourante).getJoueurs()){
							if( nom.equals(player.getNom())){
								//on renomme le nom du joueur : son nom existe deja 								
								nom += listeParties.get(numPartieCourante).getNbjoueurs();
								String msg = "pseudo existant : votre nouveau pseudo est ";
								msg += nom+"\n";
								out.write(msg.getBytes());
								break;
							}
						}
						
						//on cree le joueur
						Joueur j = new Joueur( 
								socket,in,out,nom, 
								numPartieCourante);

						String welcome = Commande.WELCOME+nom+"/\n";
						j.sendMessage(welcome);
						
						//On ajoute le joueur a la partie
						addPlayerPartie(j);


					}
				}
				else {
					out.write(Commande.ACCESSDENIED.getBytes());
					in.close();
					out.close();
					socket.close();
				}

			}
		} catch (SocketException se){
			System.err.println("On coupe les connexions car on coupe le serveur.");
			Thread.currentThread().interrupt();
			se.printStackTrace();

		} catch (IOException e) {
			System.err.println("PB CONNEXION.");
			e.printStackTrace();
		}

	}

	//Synchronized pour qu'une partie a la fois puisse etre creee
	protected synchronized static void creerPartie(){
		System.out.println("Creerpartie()");
		listeParties.add(new Partie(listeParties.size()));
		numPartieCourante = listeParties.size() -1;
		nbjoueurs = 0;
		System.out.print("Une nouvelle partie a été créée : ");
		System.out.println("partie n°"+numPartieCourante+".");
	}

	protected synchronized static void addPlayerPartie(Joueur j) 
			throws SocketException{

		System.out.print("Partie courante n°"+numPartieCourante);

		System.out.print("\tisFULL "+listeParties.get(numPartieCourante).isFull());
		
		System.out.println("\tisEnAttente "+listeParties.get(numPartieCourante).isEnAttente());

		if ( listeParties.get(numPartieCourante).isFull() || 
				!listeParties.get(numPartieCourante).isEnAttente()) {
			creerPartie();
			//System.out.println("CREATION DE PARTIE OBLIGE");
		}

		// ajout du joueur dans la partie en cours
		listeParties.get(numPartieCourante).ajoutJoueur(j);
		nbjoueurs++;
		
		System.out.print("Partie courante n°"+numPartieCourante);
		System.out.print(" Nbjoueurs = "+nbjoueurs);
		System.out.println("--------JOUEUR "+j.getNom()+" A ETE AJOUTE!");
	}

	protected synchronized static void erasePartie(Partie p){
		listeParties.remove(p);
		numPartieCourante = listeParties.size();
		
		if (listeParties.size() == 0){
			System.out.println("Il n'y a plus de parties en cours.");
			try {
				Serveur.serv.close();
				Thread.currentThread().interrupt();
				System.exit(0);
			} catch (IOException e) {
				System.err.println("Probleme Fermeture Serveur");
				e.printStackTrace();
			}
		}
	}

}